// https://leetcode.cn/problems/minesweeper/

// 题干：让我们一起来玩扫雷游戏！
//       给你一个大小为 m x n 二维字符矩阵 board ，表示扫雷游戏的盘面，其中：
//       'M' 代表一个 未挖出的 地雷，
//       'E' 代表一个 未挖出的 空方块，
//       'B' 代表没有相邻（上，下，左，右，和所有4个对角线）地雷的 已挖出的 空白方块，
//       数字（'1' 到 '8'）表示有多少地雷与这块 已挖出的 方块相邻，
//       'X' 则表示一个 已挖出的 地雷。
//       给你一个整数数组 click ，其中 click = [clickr, clickc] 表示在所有 未挖出的 方块（'M' 或者 'E'）中的下一个点击位置（clickr 是行下标，clickc 是列下标）。
//       根据以下规则，返回相应位置被点击后对应的盘面：
//       如果一个地雷（'M'）被挖出，游戏就结束了- 把它改为 'X' 。
//       如果一个 没有相邻地雷 的空方块（'E'）被挖出，修改它为（'B'），并且所有和其相邻的 未挖出 方块都应该被递归地揭露。
//       如果一个 至少与一个地雷相邻 的空方块（'E'）被挖出，修改它为数字（'1' 到 '8' ），表示相邻地雷的数量。
//       如果在此次点击中，若无更多方块可被揭露，则返回盘面。

// 示例：输入：board = [["E","E","E","E","E"],["E","E","M","E","E"],["E","E","E","E","E"],["E","E","E","E","E"]], click = [3,0]
//       输出：[["B","1","E","1","B"],["B","1","M","1","B"],["B","1","1","1","B"],["B","B","B","B","B"]]

// 碎语：有点复杂，关键是要先理解题意，返回一次点击后的结果
//       本质也是一次模拟题，进入一个格子后，判断周围的地雷数目，怎么求？
//       与之前四连通同理，这次搞一个八连通

#include <bits/stdc++.h>
using namespace std;

class Solution
{
    // 本题因为有修改行为，可以考虑不需要单开一个判断矩阵
    int dx[8] = {-1,-1,0,1,1,1,0,-1};
    int dy[8] = {0,1,1,1,0,-1,-1,-1};
    int m, n;
    
public:
    vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click)
    {
        m = board.size(), n = board[0].size();

        if (board[click[0]][click[1]] == 'M'){
            board[click[0]][click[1]] = 'X';
            return board;
        }

        dfs(board, click[0], click[1]);
        return board;
    }

    void dfs(vector<vector<char>>& board, int i, int j)
    {
        // 1.先求周围的炸弹个数
        int sum = 0;
        for (int k = 0 ; k < 8 ; k++){
            int x = i + dx[k], y = j + dy[k];

            if (x >= 0 && x < m && y >= 0 && y < n) {
                if (board[x][y] == 'M') sum++;
            }
        }

        // 2.根据求出的炸弹个数，分类讨论
        if (sum){ // 若周围有炸弹，则修改棋盘后直接退出
            board[i][j] = '0' + sum;
            return ;
        }
        else { // 若周围没有炸弹，则修改棋盘后继续递归直到退出
            board[i][j] = 'B';
            for (int k = 0 ; k < 8 ; k++){
                int x = i + dx[k], y = j + dy[k];
                if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'E') dfs(board, x, y);
            }
        }
    }
};

int main()
{
    Solution sol;
    vector<int> click = {3,0};
    vector<vector<char>> board = {{'E','E','E','E','E'},{'E','E','M','E','E'},{'E','E','E','E','E'},{'E','E','E','E','E'}};

    vector<vector<char>> index = sol.updateBoard(board, click);
    for (const auto& str : index){
        for (const auto& ch : str){
            cout << ch << " ";
        }
        cout << endl;
    }

    return 0;
}